package services

import (
	"cas_central_server/conf"
	"net/http"
	"time"

	"github.com/dgrijalva/jwt-go"
	"github.com/labstack/echo/v4"
)

func createJwtCookie(user string, remember bool) (http.Cookie, error) {
	// Create token
	token := jwt.New(jwt.SigningMethodHS256)

	// Set claims
	claims := token.Claims.(jwt.MapClaims)
	now := time.Now()
	exp := now.AddDate(0, 1, 0) // 1 month
	claims["iat"] = now.Unix()
	claims["exp"] = exp.Unix()
	claims["user"] = user

	// Generate encoded token and send it as response.
	t, err := token.SignedString([]byte(conf.Config.AppSecret))
	if err != nil {
		return http.Cookie{}, err
	}
	tokCookie := http.Cookie{
		Name:     "TOKEN",
		Path:     "/",
		Value:    t,
		HttpOnly: true,
	}
	if remember {
		tokCookie.MaxAge = int(exp.Sub(now) / time.Second)
	}
	return tokCookie, nil
}

// loginHandler 登录接口
func loginHandler(c echo.Context) error {
	u := struct {
		User     string `json:"user"`
		Password string `json:"password"`
		Remember bool   `json:"remember"`
	}{}
	if err := c.Bind(&u); err != nil {
		return badRequest("invalid inputs, error: " + err.Error())
	}

	if u.User != conf.Config.User || u.Password != conf.Config.Password {
		return unauthorized("用户名或者密码错误！")
	}

	var tokCookie http.Cookie
	tokCookie, err := createJwtCookie(u.User, u.Remember)
	if err != nil {
		return err
	}

	c.SetCookie(&tokCookie)
	return c.JSON(http.StatusOK, "登录成功!")
}

// logoutHandler 登出
func logoutHandler(c echo.Context) error {
	c.SetCookie(&http.Cookie{
		Name:     "TOKEN",
		Path:     "/",
		Value:    "",
		MaxAge:   -1,
		HttpOnly: true,
	})
	return c.JSON(http.StatusOK, "Successfully logged out!")
}

func changePasswordHandler(c echo.Context) error {
	u := struct {
		OldPassword string `json:"oldPassword"`
		NewPassword string `json:"newPassword"`
	}{}
	if err := c.Bind(&u); err != nil {
		return badRequest("invalid inputs, error: " + err.Error())
	}

	if u.OldPassword != conf.Config.Password {
		return badRequest("原密码错误！")
	}

	conf.Config.Password = u.NewPassword

	return c.JSON(http.StatusOK, "successfully changed password")
}
